package notes.java.nio.demo;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import org.junit.Test;

/**
 * 测试阻塞NIO
 * 阻塞与非阻塞是相当于网络环境的。
 */
public class N3_TestBlockingNIO {
	
	/** 服务端*/
	@Test
	public void server() throws Exception {
		// 1、获取服务端的通道 并绑定IP和端口
		ServerSocketChannel ssChannel = ServerSocketChannel.open();
		ssChannel.bind(new InetSocketAddress("127.0.0.1", 8088));
		
		// 2、获取客户端连接的通道
		SocketChannel sChannel = ssChannel.accept();
		
		// 3、写入， 获取本地写入通道
		FileChannel outChannel = FileChannel.open(Paths.get("d:/aaa.txt"), StandardOpenOption.WRITE, StandardOpenOption.CREATE);
		
		// 4、获取写入需要的缓冲区
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		
		// 5、写入
		while(sChannel.read(buffer) != -1) {
			buffer.flip(); // 切换模式
			outChannel.write(buffer);
			buffer.clear();
		}
		
		// 6、反馈给客户端信息
		buffer.put("已经收到了！！！".getBytes());
		buffer.flip();
		sChannel.write(buffer);
		
		sChannel.close();
		outChannel.close();
		ssChannel.close();
	}
	
	/** 客户端*/
	@Test
	public void client() throws Exception {
		// 1、用于网络传输的通道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8088));
		
		// 2、读取本地文件进行发送
		FileChannel inChannel = FileChannel.open(Paths.get("d:/save.txt"), StandardOpenOption.READ);
		
		// 3、用于本地读取文件的缓冲区
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		
		// 4、读取
		while(inChannel.read(buffer) != -1) {
			buffer.flip(); // 切换模式
			sChannel.write(buffer); // 发送/写入到网络通道
			buffer.clear();
		}
		
		sChannel.shutdownOutput();
		
		// 5、获取服务端反馈
		int len = 0;
		while((len = sChannel.read(buffer)) != -1){
			buffer.flip();
			System.out.println(new String(buffer.array(), 0, len));
			buffer.clear();
		}
		
		inChannel.close();
		sChannel.close();
		
	}

}
